﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Web;
using System.Web.SessionState;

namespace WebApp
{
    public class ClassHandler:IHttpHandler,IRequiresSessionState
    {
        #region IHttpHandler 成员
        private string Siteroot;

        public bool IsReusable
        {
            get { return true; }
        }

        public ClassHandler()
        {
            Siteroot = ConfigurationManager.AppSettings["SiteRoot"];
        }

        public void ProcessRequest(HttpContext context)
        {
            //throw new NotImplementedException();
            ExecuteResponse(context.Session);

        }
        void ExecuteResponse(HttpSessionState Session)
        {
            Hashtable Objects = ObjectCache.Cache().Data;
            HttpRequest request = HttpContext.Current.Request;
            Uri u = request.Url;
            if (u.OriginalString.ToLower().EndsWith(".app"))
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                int startx = 1;
                if (Siteroot != "/")
                {
                    startx = 2;
                }
                AppUrlInfo info = new AppUrlInfo(u, startx, request.HttpMethod);
                if (Objects.ContainsKey(info.ClassName.ToLower()))
                {
                    ControllerBase obj = (ControllerBase)Objects[info.ClassName.ToLower()];
                    ThreadBaseData.Get()["sys_SiteRoot"] = Siteroot;
                  
                    Type objtype = obj.GetType();
                    if (info.Params != null)
                    {
                        Type[] ptps = new Type[info.Params.Length];
                        for (int i = 0; i < info.Params.Length; i++)
                            ptps[i] = typeof(System.String);
                        Object[] pdata = new Object[info.Params.Length];
                        for (int i = 0; i < info.Params.Length; i++)
                            pdata[i] = info.Params[i];
                        MethodInfo mi = objtype.GetMethod(info.MethodName, ptps);
                        if (mi != null)
                        {
                            ParameterInfo[] pis = mi.GetParameters();
                            SortedDictionary<string, string>  pData = new SortedDictionary<string, string>();
                            for (int i = 0; i < pis.Length; i++)
                            {
                                pData.Add(pis[i].Name, info.Params[i]);
                            }
                            ThreadBaseData.Get()["sys_ParamData"] = pData;
                            mi.Invoke(obj, pdata);
                        }
                        else
                        {
                            throw new Exception("no such method - " + info.MethodName);
                        }
                    }
                    else
                    {
                        MethodInfo mi = objtype.GetMethod(info.MethodName, new Type[] { });
                        if (mi != null)
                        {
                            mi.Invoke(obj, new object[] { });
                        }
                        else
                        {
                            throw new Exception("no such method - " + info.MethodName);
                        }
                    }
                    ThreadBaseData.Get().Data.Clear();
                    sw.Stop();
                    if (ConfigurationManager.AppSettings["ShowPerformance"] == "true")
                    {
                        HttpContext.Current.Response.Write("<br />" + sw.ElapsedMilliseconds.ToString() + " ms");
                    }
                    //HttpContext.Current.Response.End();
                }
                else
                {
                    sw.Stop();
                    throw new Exception("No This Class");
                }
            }
        }


        #endregion
        class AppUrlInfo
        {
            public string ClassName
            {
                get;
                set;
            }
            public string MethodName
            {
                get;
                set;
            }
            public string[] Params
            {
                get;
                set;
            }
            public AppUrlInfo(Uri url,int index,string DefaultMethod)
            {
                ClassName = Makename(url.Segments[index]);
                
                if (url.Segments.Length > index + 1)
                {
                    MethodName = Makename(url.Segments[index + 1]);
                    
                }
                else
                {
                    MethodName = DefaultMethod;
                }
                if (url.Segments.Length > index + 2)
                {
                    Params = new string[url.Segments.Length - index - 2];
                    for (int i = index + 2; i < url.Segments.Length; i++)
                    {
                        string Value = url.Segments[i];
                        Value = Value.IndexOf('.') > -1 ? Value.Split('.')[0] : Value;
                        if (Value.EndsWith("/"))
                        {
                            Value = Value.Substring(0, Value.Length - 1);
                        }
                        Params[i - index - 2] = Value;
                    }
                }
            }
            private string Makename(string Ori)
            {
                if (Ori.EndsWith("/"))
                    Ori = Ori.Substring(0, Ori.Length - 1);
                string Titled = Ori.ToUpper()[0] + Ori.ToLower().Substring(1);
                if (Titled.IndexOf('.') > 0)
                {
                    return Titled.Split('.')[0];
                }
                return Titled;
            }

        }


    }
}
